﻿using System;
using Moonlite.ExtensionApi.ControlInterfaces;
using Moonlite.Languages.vJass;
using Moonlite.Languages.vJass.CodeObj;
using Moonlite.Platform.General;
using Storm.TextEditor.Editor.CodeCompletion;

namespace Moonlite.Services.CodeCompletion
{
    public static class JassObjectHelper
    {
        public static JParser Parser { get; set; }

        public static Function GetFunctionFromName(string name)
        {
            if (Parser != null)
            {
                foreach (Function function in Parser.Functions)
                {
                    if (function.Name == name)
                    {
                        return function;
                    }
                }
            }

            return null;
        }

        public static Function GetFunctionInLibraryFromName(Library library, string name)
        {
            if (Parser != null)
            {
                foreach (Function function in library.Functions)
                {
                    if (function.Name == name)
                    {
                        return function;
                    }
                }
            }

            return null;
        }

        public static Function GetFunctionInScopeFromName(Scope scope, string name)
        {
            if (Parser != null)
            {
                foreach (Function function in scope.Functions)
                {
                    if (function.Name == name)
                    {
                        return function;
                    }
                }
            }

            return null;
        }

        public static Library GetLibraryFromName(string name)
        {
            if (Parser != null)
            {
                foreach (Library library in Parser.Libraries)
                {
                    if (library.Name == name)
                    {
                        return library;
                    }
                }
            }

            return null;
        }

        public static Scope GetScopeFromName(string name)
        {
            if (Parser != null)
            {
                foreach (Scope scope in Parser.Scopes)
                {
                    if (scope.Name == name)
                    {
                        return scope;
                    }
                }
            }

            return null;
        }

        public static Scope GetScopeInLibraryFromName(Library library, string name)
        {
            if (Parser != null)
            {
                foreach (Scope scope in library.Scopes)
                {
                    if (scope.Name == name)
                    {
                        return scope;
                    }
                }
            }

            return null;
        }

        public static Struct GetStructFromName(string name)
        {
            if (Parser != null)
            {
                foreach (Struct structX in Parser.Structs)
                {
                    if (structX.Name == name)
                    {
                        return structX;
                    }
                }
            }

            return null;
        }

        public static Struct GetLocalStructFromNameInFunction(string name, Function function)
        {
            if (Parser != null)
            {
                foreach (FunctionVariable variable in function.Variables)
                {
                    Struct structX = GetStructFromName(variable.Type);
                    if (variable.Name == name && structX != null)
                    {
                        return structX;
                    }
                }
            }

            return null;
        }

        public static Struct GetLocalStructFromNameInMethod(string name, Method method)
        {
            if (Parser != null)
            {
                foreach (MethodVariable variable in method.Variables)
                {
                    Struct structX = GetStructFromName(variable.Type);
                    if (variable.Name == name && structX != null)
                    {
                        return structX;
                    }
                }
            }

            return null;
        }

        public static Struct GetStructInLibraryFromName(Library library, string name)
        {
            if (Parser != null)
            {
                foreach (Struct structX in library.Structs)
                {
                    if (structX.Name == name)
                    {
                        return structX;
                    }
                }
            }

            return null;
        }

        public static Struct GetStructInScopeFromName(Scope scope, string name)
        {
            if (Parser != null)
            {
                foreach (Struct structX in scope.Structs)
                {
                    if (structX.Name == name)
                    {
                        return structX;
                    }
                }
            }

            return null;
        }

        public static Method GetMethodFromName(Struct structX, string name)
        {
            if (Parser != null)
            {
                foreach (Method method in structX.Methods)
                {
                    if (method.Name == name)
                    {
                        return method;
                    }
                }
            }

            return null;
        }

        public static bool IsValidTypeName(string name)
        {
            foreach (DefaultCompletionData data in JassNativeObjectsReader.Types)
            {
                if (data.Text == name)
                {
                    return true;
                }
            }

            foreach (Struct structX in Parser.Structs)
            {
                if (structX.Name == name)
                {
                    return true;
                }
            }

            return false;
        }

        public static Obj GetObjFromCaretPosition()
        {
            Obj obj = null;

            foreach (Library library in Parser.Libraries)
            {
                if (IsCaretInObject(library) == true)
                {
                    obj = library;
                }
            }

            foreach (Scope scope in Parser.Scopes)
            {
                if (IsCaretInObject(scope) == true)
                {
                    obj = scope;
                }
            }

            foreach (Struct structX in Parser.Structs)
            {
                if (IsCaretInObject(structX) == true)
                {
                    obj = structX;
                }

                foreach (Method method in structX.Methods)
                {
                    if (IsCaretInObject(method) == true)
                    {
                        obj = method;
                    }
                }
            }

            foreach (Globals globals in Parser.Globals)
            {
                if (IsCaretInObject(globals) == true)
                {
                    obj = globals;
                }
            }

            foreach (Function function in Parser.Functions)
            {
                if (IsCaretInObject(function) == true)
                {
                    obj = function;
                }
            }

            return obj;
        }

        public static Struct GetStructFromCaretPosition()
        {
            foreach (Struct structX in Parser.Structs)
            {
                if (IsCaretInObject(structX) == true)
                {
                    return structX;
                }
            }

            return null;
        }

        public static bool IsCaretInObject(Obj obj)
        {
            if (Global.Instance.IsCurrentTabPageTextEditor() == false)
            {
                return false;
            }

            ITextEditor textEditor = Global.Instance.GetCurrentTabPageTextEditor();
            return textEditor.InnerTextEditor.Caret.Position.Y >= obj.StartLine &&
                textEditor.InnerTextEditor.Caret.Position.Y <= obj.EndLine;
        }
    }
}
